import { ref, computed, getCurrentInstance, watch, nextTick, onMounted } from 'vue'
import { VWindowProps, DialogEmits, UPDATE_MODEL_EVENT } from './vwindowProps'
import type { CSSProperties, Ref, SetupContext } from 'vue'
import { addUnit } from '@v-model/shared--utils'
import { useTimeoutFn } from '@vueuse/core'
import { defaultNamespace, useId, useZIndex } from '@v-model/shared--hooks'
// import { useGlobalConfig } from '../../config-provider'

declare const isClient: boolean

export const useVwindow = (props: VWindowProps, targetRef: Ref<HTMLElement | undefined>) => {
  const instance = getCurrentInstance()!
  const emit = instance.emit as SetupContext<DialogEmits>['emit']
  const { nextZIndex } = useZIndex()

  const zIndex = ref(props.zIndex || nextZIndex())

  let lastPosition = ''
  const titleId = useId()
  const bodyId = useId()
  const visible = ref(false)
  const closed = ref(false)
  const rendered = ref(false) // when desctroyOnClose is true, we initialize it as false vise versa

  let openTimer: (() => void) | undefined = undefined
  let closeTimer: (() => void) | undefined = undefined

  // const namespace = useGlobalConfig('namespace', defaultNamespace)

  const style = computed<CSSProperties>(() => {
    const style: CSSProperties = {}
    const varPrefix = `--v-dialog` as const
    if (!props.fullscreen) {
      if (props.top) {
        style[`margin-top`] = props.top
      }

      if (props.initWidth || props.width) {
        style[`width`] = addUnit(props.initWidth || props.width)
      }

      if (props.initHeight || props.height) {
        /**
         * 计算 设置 margin-top 的位置
         */
        let height = props.initHeight || props.height

        if (typeof height === 'string') {
          if (height.includes('px')) {
            style[`margin-top`] = `calc(50vh - ${addUnit(height)} / 2)`
          }

          if (height.includes('%') || height.includes('vh')) {
            let defaultUnit = height.includes('%') ? '%' : 'vh'
            if (parseInt(height) >= 85) {
              style[`margin-top`] = `calc((100${defaultUnit} - ${addUnit(height)}) / ${defaultUnit === '%' ? 7 : 2})`
            }
          }
        }

        style[`height`] = addUnit(height)
      }
    }
    return style
  })

  const overlayDialogStyle = computed<CSSProperties>(() => {
    if (props.alignCenter) {
      return { display: 'flex' }
    }
    return {}
  })

  function afterEnter() {
    emit('opened')
  }

  function afterLeave() {
    emit('closed')
    emit(UPDATE_MODEL_EVENT, false)
    if (props.destroyOnClose) {
      rendered.value = false
    }
  }

  function beforeLeave() {
    emit('close')
  }

  function open() {
    closeTimer?.()
    openTimer?.()

    if (props.openDelay && props.openDelay > 0) {
      ;({ stop: openTimer } = useTimeoutFn(() => doOpen(), props.openDelay))
    } else {
      doOpen()
    }
  }

  function close() {
    openTimer?.()
    closeTimer?.()

    if (props.closeDelay && props.closeDelay > 0) {
      ;({ stop: closeTimer } = useTimeoutFn(() => doClose(), props.closeDelay))
    } else {
      doClose()
    }
  }

  function handleClose() {
    function hide(shouldCancel?: boolean) {
      if (shouldCancel) return
      closed.value = true
      visible.value = false
    }

    if (props.beforeClose) {
      props.beforeClose(hide)
    } else {
      close()
    }
  }

  function onModalClick() {
    if (props.closeOnClickModal) {
      handleClose()
    }
  }

  function doOpen() {
    // if (!isClient) return
    visible.value = true
  }

  function doClose() {
    visible.value = false
  }

  function onOpenAutoFocus() {
    emit('openAutoFocus')
  }

  function onCloseAutoFocus() {
    emit('closeAutoFocus')
  }

  function onFocusoutPrevented(event: CustomEvent) {
    if (event.detail?.focusReason === 'pointer') {
      event.preventDefault()
    }
  }

  if (props.lockScroll) {
    // useLockscreen(visible)
  }

  function onCloseRequested() {
    if (props.closeOnPressEscape) {
      handleClose()
    }
  }

  watch(
    () => props.modelValue,
    (val) => {
      if (val) {
        closed.value = false
        open()
        rendered.value = true // enables lazy rendering
        zIndex.value = props.zIndex ? zIndex.value++ : nextZIndex()
        // this.$el.addEventListener('scroll', this.updatePopper)
        nextTick(() => {
          emit('open')
          if (targetRef.value) {
            targetRef.value.scrollTop = 0
          }
        })
      } else {
        // this.$el.removeEventListener('scroll', this.updatePopper
        if (visible.value) {
          close()
        }
      }
    }
  )

  watch(
    () => props.fullscreen,
    (val) => {
      if (!targetRef.value) return
      if (val) {
        lastPosition = targetRef.value.style.transform
        targetRef.value.style.transform = ''
      } else {
        targetRef.value.style.transform = lastPosition
      }
    }
  )

  onMounted(() => {
    if (props.modelValue) {
      visible.value = true
      rendered.value = true // enables lazy rendering
      open()
    }
  })

  // 确认保存
  const confirm = () => {
    emit('confirm')
  }

  // 取消操作
  const cancel = () => {
    if (props.isVerify) return emit('cancel')
    emit(UPDATE_MODEL_EVENT, false)
  }

  // 拖拽右下角改变大小
  const MakeResizable = function (e: any) {
    var eve = e || window.event
    var pointerId = e.pointerId
    const dragbar = e.target
    const CtlEl: any = targetRef.value
    if (typeof dragbar.setPointerCapture != 'undefined') {
      //SetCapture捕捉鼠标到指定的元素
      //dragAry.setCapture();
      dragbar.setPointerCapture(pointerId)
    }
    if (typeof dragbar.setPointerCapture != 'undefined') {
      //SetCapture捕捉鼠标到指定的元素
      //dragAry.setCapture();
      dragbar.setPointerCapture(pointerId)
    }
    let ElPos = {
      __point_s_x__: e.clientX, //点击鼠标时储存x轴
      __point_s_y__: e.clientY, //点击鼠标时储存y轴
      __e_rect_x__: CtlEl.offsetLeft,
      __e_rect_y__: CtlEl.offsetTop,
      __e_rect_w__: CtlEl.offsetWidth,
      __e_rect_h__: CtlEl.offsetHeight,
    }
    document.onmousemove = function (e) {
      var e = e || window.event
      if (e.preventDefault) {
        e.preventDefault()
      }
      const CtlEl: any = targetRef.value
      var iE = e
      if (iE.clientY == 0) {
        //向左移动
        targetRef.value!.style.width = ElPos.__e_rect_w__ + (iE.clientX - ElPos.__point_s_x__) + 'px'
      } else if (iE.clientX == 0) {
        //向右移动
        targetRef.value!.style.height = ElPos.__e_rect_h__ + (iE.clientY - ElPos.__point_s_y__) + 'px'
      } else if (iE.clientY != 0 && iE.clientX != 0) {
        //同时移动
        targetRef.value!.style.width = ElPos.__e_rect_w__ + (iE.clientX - ElPos.__point_s_x__) + 'px'
        targetRef.value!.style.height = ElPos.__e_rect_h__ + (iE.clientY - ElPos.__point_s_y__) + 'px'
      }
      if (typeof props.onresize == 'function') {
        props.onresize(CtlEl.offsetWidth, CtlEl.offsetHeight)
      }
    }
    document.onmouseup = function (e) {
      //当鼠标弹起来的时候不再移动
      this.onmousemove = null
      //修复低版本ie bug
      if (typeof dragbar.releasePointerCapture != 'undefined') {
        dragbar.releasePointerCapture(pointerId)
      }
    }
  }

  return {
    afterEnter,
    afterLeave,
    beforeLeave,
    handleClose,
    onModalClick,
    close,
    doClose,
    onOpenAutoFocus,
    onCloseAutoFocus,
    onCloseRequested,
    onFocusoutPrevented,
    MakeResizable,
    confirm,
    cancel,
    closed,
    style,
    overlayDialogStyle,
    rendered,
    visible,
    zIndex,
    titleId,
    bodyId,
  }
}
